<template>
    <div
        class="floating-fig rabbit"
        :class="{ minimized, active }"
        :style="rootStyle"
        @pointerdown.prevent="onPointerDown"
        @contextmenu.prevent="onContextMenu"
        @click.stop="onClick"
        @dblclick.stop="onDblClick"
        @pointerenter="onPointerEnter"
        @pointerleave="onPointerLeave"
    >
        <div class="fig-wrap">
            <svg
                viewBox="0 0 140 160"
                xmlns="http://www.w3.org/2000/svg"
                class="fig-svg"
            >
                <!-- ears -->
                <g class="ear left">
                    <ellipse
                        class="ear-outer"
                        cx="40"
                        cy="28"
                        rx="14"
                        ry="34"
                        fill="#fff"
                        stroke="#f3e8ff"
                        stroke-width="2"
                    />
                    <ellipse
                        class="ear-inner"
                        cx="40"
                        cy="28"
                        rx="8"
                        ry="22"
                        fill="#ffdfe8"
                    />
                </g>
                <g class="ear right">
                    <ellipse
                        class="ear-outer"
                        cx="100"
                        cy="28"
                        rx="14"
                        ry="34"
                        fill="#fff"
                        stroke="#f3e8ff"
                        stroke-width="2"
                    />
                    <ellipse
                        class="ear-inner"
                        cx="100"
                        cy="28"
                        rx="8"
                        ry="22"
                        fill="#ffdfe8"
                    />
                </g>
                <!-- head -->
                <g class="head">
                    <circle
                        class="head-bg"
                        cx="70"
                        cy="64"
                        r="36"
                        fill="#fff"
                        stroke="#f1e8ff"
                        stroke-width="2"
                    />
                    <!-- eyes -->
                    <g class="eyes">
                        <ellipse
                            class="eye left"
                            cx="56"
                            cy="60"
                            rx="4"
                            ry="6"
                            fill="#3b3b3b"
                        />
                        <ellipse
                            class="eye right"
                            cx="84"
                            cy="60"
                            rx="4"
                            ry="6"
                            fill="#3b3b3b"
                        />
                        <circle
                            class="eye-spark left"
                            cx="54"
                            cy="58"
                            r="1.6"
                            fill="#fff"
                            opacity="0.9"
                        />
                        <circle
                            class="eye-spark right"
                            cx="82"
                            cy="58"
                            r="1.6"
                            fill="#fff"
                            opacity="0.9"
                        />
                    </g>
                    <!-- blush -->
                    <ellipse
                        cx="50"
                        cy="72"
                        rx="6"
                        ry="3"
                        fill="#ffd6e6"
                        opacity="0.9"
                    />
                    <ellipse
                        cx="90"
                        cy="72"
                        rx="6"
                        ry="3"
                        fill="#ffd6e6"
                        opacity="0.9"
                    />
                    <!-- nose -->
                    <path
                        class="nose"
                        d="M70 68 q4 6 0 10 q-4 -4 0 -10"
                        fill="#ff9fb0"
                    />
                </g>
                <!-- body -->
                <g class="body">
                    <ellipse
                        cx="70"
                        cy="112"
                        rx="40"
                        ry="30"
                        fill="#fff"
                        stroke="#f1e8ff"
                        stroke-width="2"
                    />
                    <!-- tail -->
                    <circle
                        class="tail"
                        cx="108"
                        cy="112"
                        r="8"
                        fill="#ffd6e6"
                    />
                </g>
            </svg>
            <button
                class="toggle-btn"
                @click.stop="toggleMinimized"
                :title="minimized ? '展开' : '收起'"
            >
                {{ minimized ? "▷" : "▢" }}
            </button>
        </div>

        <div v-if="menuVisible" class="fig-menu" :style="menuStyle" @click.stop>
            <ul>
                <li @click="menuAction('home')">首页</li>
                <li @click="menuAction('settings')">设置</li>
                <li @click="menuAction('about')">关于</li>
            </ul>
        </div>
    </div>
</template>

<script>
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";

export default {
    name: "FloatingFig",
    setup() {
        const router = useRouter();
        const store = useStore();

        const pos = ref({
            x: window.innerWidth - 140 - 20,
            y: window.innerHeight - 160,
        });
        const minimized = ref(false);
        const active = ref(false);

        if (store && store.state && store.state.settings) {
            const s = store.state.settings;
            if (s.siteAccent)
                document.documentElement.style.setProperty(
                    "--accent",
                    s.siteAccent,
                );
            if (s.figPos) pos.value = s.figPos;
            if (typeof s.figMin !== "undefined") minimized.value = !!s.figMin;
        }

        const dragging = ref(false);
        const offset = ref({ x: 0, y: 0 });
        let moveHandler = null;
        let upHandler = null;

        const menuVisible = ref(false);
        const menuPos = ref({ x: 0, y: 0 });

        function clampPosition(x, y) {
            const w = minimized.value ? 48 : 140;
            const h = minimized.value ? 56 : 160;
            const maxX = window.innerWidth - w - 10;
            const maxY = window.innerHeight - h - 10;
            return {
                x: Math.max(10, Math.min(maxX, x)),
                y: Math.max(10, Math.min(maxY, y)),
            };
        }

        function onPointerDown(e) {
            if (e.button !== 0) return;
            dragging.value = true;
            offset.value = {
                x: e.clientX - pos.value.x,
                y: e.clientY - pos.value.y,
            };

            moveHandler = (ev) => {
                if (!dragging.value) return;
                const nx = ev.clientX - offset.value.x;
                const ny = ev.clientY - offset.value.y;
                const p = clampPosition(nx, ny);
                pos.value.x = p.x;
                pos.value.y = p.y;
            };

            upHandler = () => {
                dragging.value = false;
                window.removeEventListener("pointermove", moveHandler);
                window.removeEventListener("pointerup", upHandler);
                try {
                    localStorage.setItem(
                        "floatingFigPos",
                        JSON.stringify(pos.value),
                    );
                } catch (e) {
                    console.error(e);
                }
                if (store) store.dispatch("settings/setFigPos", pos.value);
            };

            window.addEventListener("pointermove", moveHandler);
            window.addEventListener("pointerup", upHandler);
        }

        function onContextMenu(e) {
            menuVisible.value = true;
            menuPos.value = { x: e.clientX + 10, y: e.clientY + 10 };
        }

        function onClick() {
            menuVisible.value = !menuVisible.value;
            menuPos.value = {
                x: pos.value.x + (minimized.value ? 48 : 140) - 140,
                y: pos.value.y,
            };
        }

        function onDblClick() {
            const w = minimized.value ? 48 : 140;
            const h = minimized.value ? 56 : 160;
            pos.value = {
                x: (window.innerWidth - w) / 2,
                y: (window.innerHeight - h) / 2,
            };
            try {
                localStorage.setItem(
                    "floatingFigPos",
                    JSON.stringify(pos.value),
                );
            } catch (e) {
                console.error(e);
            }
            if (store) store.dispatch("settings/setFigPos", pos.value);
        }

        function toggleMinimized() {
            minimized.value = !minimized.value;
            try {
                localStorage.setItem(
                    "floatingFigMin",
                    minimized.value ? "1" : "0",
                );
            } catch (e) {
                console.error(e);
            }
            if (store) store.dispatch("settings/setFigMin", minimized.value);
        }

        function onPointerEnter() {
            active.value = true;
        }
        function onPointerLeave() {
            active.value = false;
        }

        function menuAction(key) {
            menuVisible.value = false;
            const map = { home: "/", settings: "/settings", about: "/about" };
            const path = map[key] || "/";
            try {
                router.push(path);
            } catch (e) {
                console.warn("router push failed", e);
            }
            const evt = new CustomEvent("floating-fig-action", {
                detail: { action: key },
            });
            window.dispatchEvent(evt);
        }

        const rootStyle = computed(() => ({
            left: pos.value.x + "px",
            top: pos.value.y + "px",
            width: minimized.value ? "48px" : "140px",
            height: minimized.value ? "56px" : "160px",
        }));
        const menuStyle = computed(() => ({
            left: menuPos.value.x + "px",
            top: menuPos.value.y + "px",
        }));

        onMounted(() => {
            const onDocClick = () => {
                menuVisible.value = false;
            };
            window.addEventListener("click", onDocClick);

            const onSettings = (e) => {
                const d = e.detail || {};
                if (d.accent)
                    document.documentElement.style.setProperty(
                        "--accent",
                        d.accent,
                    );
                if (typeof d.float !== "undefined") {
                    if (!d.float)
                        document
                            .querySelector(".floating-fig")
                            ?.classList.add("minimized");
                    else
                        document
                            .querySelector(".floating-fig")
                            ?.classList.remove("minimized");
                }
                if (d.resetFig) {
                    pos.value = {
                        x: window.innerWidth - 140 - 20,
                        y: window.innerHeight - 160,
                    };
                    minimized.value = false;
                    if (store) {
                        store.dispatch("settings/setFigPos", pos.value);
                        store.dispatch("settings/setFigMin", false);
                    }
                }
            };
            window.addEventListener("settings-changed", onSettings);

            onBeforeUnmount(() => {
                window.removeEventListener("click", onDocClick);
                window.removeEventListener("settings-changed", onSettings);
            });
        });

        onBeforeUnmount(() => {
            if (moveHandler)
                window.removeEventListener("pointermove", moveHandler);
            if (upHandler) window.removeEventListener("pointerup", upHandler);
        });

        return {
            pos,
            minimized,
            active,
            menuVisible,
            menuPos,
            onPointerDown,
            onContextMenu,
            onClick,
            onDblClick,
            toggleMinimized,
            onPointerEnter,
            onPointerLeave,
            menuAction,
            rootStyle,
            menuStyle,
        };
    },
};
</script>

<style scoped>
.floating-fig {
    position: fixed;
    z-index: 9999;
    cursor: grab;
    transition:
        transform 0.12s,
        width 0.12s,
        height 0.12s;
    user-select: none;
    transform-origin: center;
    animation: floaty 4s ease-in-out infinite;
    display: flex;
    align-items: flex-start;
}
.floating-fig:active {
    cursor: grabbing;
}
.fig-wrap {
    position: relative;
    width: 100%;
    height: 100%;
}
.fig-svg {
    width: 100%;
    height: 100%;
    display: block;
    border-radius: 8px;
    overflow: visible;
}
.ear {
    transform-origin: center bottom;
}
.ear.left {
    transform-origin: 40px 60px;
}
.ear.right {
    transform-origin: 100px 60px;
}
.eye {
    transform-origin: center;
}
.tail {
    transform-origin: center;
}
.head {
    transform-origin: 70px 64px;
}

@keyframes floaty {
    0% {
        transform: translateY(0);
    }
    45% {
        transform: translateY(-10px) scaleY(1.01);
    }
    50% {
        transform: translateY(-16px) scale(1.02);
    }
    100% {
        transform: translateY(0);
    }
}
@keyframes ear-twitch {
    0% {
        transform: rotate(0deg);
    }
    30% {
        transform: rotate(-12deg);
    }
    60% {
        transform: rotate(6deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
@keyframes blink {
    0% {
        transform: scaleY(1);
    }
    45% {
        transform: scaleY(1);
    }
    50% {
        transform: scaleY(0.04);
    }
    55% {
        transform: scaleY(1);
    }
    100% {
        transform: scaleY(1);
    }
}
@keyframes tail-wag {
    0% {
        transform: rotate(0deg);
    }
    50% {
        transform: rotate(-12deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
@keyframes head-tilt {
    0% {
        transform: rotate(0deg);
    }
    50% {
        transform: rotate(-3deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
@keyframes spark {
    0% {
        opacity: 0;
    }
    30% {
        opacity: 0;
    }
    40% {
        opacity: 1;
    }
    55% {
        opacity: 0.2;
    }
    100% {
        opacity: 0;
    }
}

.ear.left {
    animation: ear-twitch 3.6s ease-in-out infinite;
}
.ear.right {
    animation: ear-twitch 4.2s ease-in-out 0.6s infinite;
}
.eye {
    animation: blink 4.5s steps(1, end) infinite;
}
.tail {
    animation: tail-wag 4s ease-in-out infinite;
}
.head {
    animation: head-tilt 6s ease-in-out infinite;
}

/* active (hover/attention) state - livelier */
.rabbit.active .ear.left {
    animation-duration: 2.2s;
}
.rabbit.active .ear.right {
    animation-duration: 2.6s;
    animation-delay: 0.2s;
}
.rabbit.active .eye {
    animation-duration: 3.2s;
}
.rabbit.active .tail {
    animation-duration: 2.4s;
}
.rabbit.active .head {
    animation-duration: 3s;
}
.rabbit.active .eye-spark {
    animation: spark 1.2s ease-in-out infinite;
}

.toggle-btn {
    position: absolute;
    right: 6px;
    top: 6px;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 6px;
    padding: 2px 6px;
    font-size: 12px;
    cursor: pointer;
}
.toggle-btn:hover {
    background: #fff;
}
.minimized {
    animation: none;
}
.fig-menu {
    position: fixed;
    background: white;
    border-radius: 8px;
    padding: 6px 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    border: 1px solid rgba(0, 0, 0, 0.06);
    min-width: 120px;
    z-index: 10000;
}
.fig-menu ul {
    list-style: none;
    padding: 6px 0;
    margin: 0;
}
.fig-menu li {
    padding: 8px 12px;
    cursor: pointer;
    color: #333;
    border-radius: 6px;
}
.fig-menu li:hover {
    background: rgba(124, 92, 255, 0.06);
    color: var(--accent, #7c5cff);
}
</style>
